package com.ycrlkj.android.modulescore.main.activity;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.Manifest;
import android.annotation.SuppressLint;
import android.os.Bundle;
import android.view.KeyEvent;

import com.alibaba.android.arouter.facade.annotation.Route;
import com.alibaba.android.arouter.launcher.ARouter;
import com.alibaba.android.arouter.utils.TextUtils;
import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationListener;
import com.amap.api.location.CoordinateConverter;
import com.amap.api.location.DPoint;
import com.amap.api.navi.NaviSetting;
import com.blankj.utilcode.util.SPStaticUtils;
import com.blankj.utilcode.util.ToastUtils;
import com.lxj.xpopup.impl.LoadingPopupView;
import com.lxj.xpopup.interfaces.OnConfirmListener;
import com.ycrlkj.android.modulesbase.libbase.utils.Logger;
import com.ycrlkj.android.modulescore.main.BR;
import com.ycrlkj.android.modulescore.main.R;
import com.ycrlkj.android.modulescore.main.apiservice.XxAppointmentApiService;
import com.ycrlkj.android.modulescore.main.apiservice.XxStationApiService;
import com.ycrlkj.android.modulescore.main.databinding.ActivityXxAppointmentListBinding;
import com.ycrlkj.android.modulescore.main.entity.Query.XxStationQuery;
import com.ycrlkj.android.modulescore.main.entity.XxAppointment;
import com.ycrlkj.android.modulescore.main.entity.XxStation;
import com.ycrlkj.android.modulespublic.common.base.DataBindingRecyclerViewAdapter;
import com.ycrlkj.android.modulespublic.common.constant.RoutePath;
import com.ycrlkj.android.modulespublic.common.net.exception.ApiException;
import com.ycrlkj.android.modulespublic.common.net.exception.ApiExceptionHandler;
import com.ycrlkj.android.modulespublic.common.net.exception.ErrorConsumer;
import com.ycrlkj.android.modulespublic.common.net.transformer.ResponseTransformer;
import com.ycrlkj.android.modulespublic.common.utils.xpopup.XPopupUtil;
import com.ycrlkj.android.modulespublic.common.widget.titlebar.MTitleBar;

import java.util.List;

import javax.inject.Inject;

import dagger.hilt.android.AndroidEntryPoint;
import pub.devrel.easypermissions.EasyPermissions;

@AndroidEntryPoint
@Route(path = RoutePath.PAGE_XX_APPOINTMENT_LIST)
public class XxAppointmentListActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks {

    @Inject
    XxAppointmentApiService xxAppointmentApiService;

    @Inject
    XxStationApiService xxStationApiService;

    private ActivityXxAppointmentListBinding binding;

    private RecyclerView recyclerView;

    private DataBindingRecyclerViewAdapter<XxAppointment> adapter;

    private AMapLocationClient aMapLocationClient;

    List<XxAppointment> xxAppointments;

    DPoint locationLatLng;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = ActivityXxAppointmentListBinding.inflate(getLayoutInflater());

        setContentView(binding.getRoot());

        initTitleBar();
        initAdapter();

        initPermissions();
        getAll();
    }

    public void initAdapter() {
        recyclerView = binding.recyclerView;
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        adapter = new DataBindingRecyclerViewAdapter<>(this, R.layout.item_xx_appointment, BR.xxAppointment, R.id.btn_doCheck);

        adapter.setOnItemClickListener(new DataBindingRecyclerViewAdapter.OnItemClickListener<XxAppointment>() {
            @Override
            public void onItemClickListener(XxAppointment item, int i) {
                String id = item.getId();
                ARouter.getInstance().build(RoutePath.PAGE_XX_APPOINTMENT_DETAIL).withString("id", id).navigation();
            }

        });

        adapter.setOnItemChildClickListener(new DataBindingRecyclerViewAdapter.OnItemChildClickListener<XxAppointment>() {
            @Override
            public void onItemChildClickListener(XxAppointment item, int position) {
                doCheck(item.getId());
            }
        });

        recyclerView.setAdapter(adapter);
    }


    @SuppressLint("CheckResult")
    public void getAll() {
        LoadingPopupView loadingPopupView = XPopupUtil.showLoading(this);
        XPopupUtil.hideLoadingDelay(loadingPopupView);

        String userId = SPStaticUtils.getString("userId");
        if (TextUtils.isEmpty(userId)) {
            XPopupUtil.showModal(XxAppointmentListActivity.this, "请先登录", new OnConfirmListener() {
                @Override
                public void onConfirm() {
                    toLogin();
                }
            });
        } else {
            xxAppointmentApiService.getAllByUserId(userId)
                    .compose(ResponseTransformer.obtain())
                    .subscribe(xxAppointments -> {

                                this.xxAppointments = xxAppointments;

                                adapter.add(xxAppointments);

                                //获取当前定位
                                initAMapLocationListener();

                                XPopupUtil.hideLoading(loadingPopupView);
                            },
                            new ErrorConsumer() {
                                @Override
                                protected void error(ApiException e) {
                                    XPopupUtil.hideLoading(loadingPopupView);
                                    ApiExceptionHandler.doWith(XxAppointmentListActivity.this, e);
                                }
                            });
        }

    }

    @SuppressLint("CheckResult")
    public void doCheck(String id) {
        LoadingPopupView loadingPopupView = XPopupUtil.showLoading(this);
        XPopupUtil.hideLoadingDelay(loadingPopupView);

        xxAppointmentApiService.doCheckById(id)
                .compose(ResponseTransformer.obtain())
                .subscribe(resultData -> {
                            XPopupUtil.hideLoading(loadingPopupView);
                            ToastUtils.showLong(resultData.getToast());
                        },
                        new ErrorConsumer() {
                            @Override
                            protected void error(ApiException e) {
                                XPopupUtil.hideLoading(loadingPopupView);
                                ApiExceptionHandler.doWith(XxAppointmentListActivity.this, e);
                            }
                        });

    }


    public void toLogin() {
        ARouter.getInstance().build(RoutePath.PAGE_LOGIN).navigation();
    }

    public void toAdd() {
        ARouter.getInstance().build(RoutePath.PAGE_XX_APPOINTMENT_ADD).navigation();
    }

    public void initTitleBar() {
        MTitleBar titleBar = binding.mTitleBar;
        titleBar.setBtnEvents(new MTitleBar.BtnEvents() {
            @Override
            public void setBtnLeftOnClickListener() {
                finish();
            }

            @Override
            public void setBtnRightOnClickListener() {
                toAdd();
            }
        });

    }

    //此页面需要重定义物理返回按钮的功能, 结束当前activity, 否则页面会在 新建预约 和 预约列表 两个页面死循环
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        //拦截系统键盘按下事件, 如果是按下返回按钮
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            finish();
            //返回true中断当前事件, 不再向上冒泡
            return true;
        } else {
            //如果按下的不是返回按钮, 则执行按钮默认操作
            return super.onKeyDown(keyCode, event);
        }
    }


    public void initAMapLocationListener() {
        AMapLocationListener aMapLocationListener = new AMapLocationListener() {
            @Override
            public void onLocationChanged(AMapLocation aMapLocation) {

                if (aMapLocation.getErrorCode() != 0) {
                    Logger.e("获取定位失败, " + aMapLocation.getErrorInfo());
                    ToastUtils.showLong("获取定位失败, " + aMapLocation.getErrorInfo());
                    return;
                }

                int locationType = aMapLocation.getLocationType();//获取当前定位结果来源，如网络定位结果，详见定位类型表
                locationLatLng = new DPoint(aMapLocation.getLatitude(), aMapLocation.getLongitude());

                //停止定位(只定位一次)
                aMapLocationClient.stopLocation();

                setLocationDistance();
            }
        };


        try {
            NaviSetting.updatePrivacyShow(this, true, true);
            NaviSetting.updatePrivacyAgree(this, true);

            aMapLocationClient = new AMapLocationClient(getApplicationContext());

            aMapLocationClient.setLocationListener(aMapLocationListener);

            AMapLocationClientOption option = new AMapLocationClientOption();
            //设置定位模式为高精度模式，Battery_Saving为低功耗模式，Device_Sensors是仅设备模式
            option.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
            //设置定位场景，目前支持三种场景（签到、出行、运动，默认无场景）
            option.setLocationPurpose(AMapLocationClientOption.AMapLocationPurpose.SignIn);
            //获取一次定位结果, 默认为false
            option.setOnceLocation(true);
            //是否返回地址信息（默认true）
            option.setNeedAddress(true);
            //设置定位间隔,单位毫秒,默认为2000ms
            //option.setInterval(2000);

            //给定位客户端对象设置定位参数
            aMapLocationClient.setLocationOption(option);
            //设置场景模式后最好调用一次stop，再调用start以保证场景模式生效
            aMapLocationClient.stopLocation();

            //启动定位
            aMapLocationClient.startLocation();
        }catch(Exception e){
            ToastUtils.showLong("定位失败");
            e.printStackTrace();
        }

    }

    @SuppressLint("CheckResult")
    public void setLocationDistance() {
        XxStationQuery xxStationQuery = new XxStationQuery();
        xxStationApiService.getAll(xxStationQuery)
                .compose(ResponseTransformer.obtain())
                .subscribe(xxStations -> {
                            xxAppointments.forEach(xxAppointment -> {
                                xxStations.forEach(xxStation -> {
                                    Double xxStationLat = xxStation.getLat();
                                    Double xxStationLng = xxStation.getLng();

                                    if (xxStationLat == 0 || xxStationLng == 0)
                                        return;

                                    float dis = CoordinateConverter.calculateLineDistance(locationLatLng, new DPoint(xxStationLat, xxStationLng));
                                    int LocationDistance = (int) dis;

                                    xxAppointment.setLocationDistance(LocationDistance);

                                    Logger.e(" xxAppointment = " + xxAppointment);

                                });
                            });

                            adapter.replace(this.xxAppointments);
                        },
                        new ErrorConsumer() {
                            @Override
                            protected void error(ApiException e) {
                                Logger.e(" 获取站点列表失败");
                            }
                        });
    }

    /* #region ========================= 权限管理 开始 ====================== */
    public void initPermissions() {
        //定位需要申请的权限
        String[] perms = {
                Manifest.permission.ACCESS_FINE_LOCATION,
                Manifest.permission.ACCESS_COARSE_LOCATION,
                Manifest.permission.CHANGE_WIFI_STATE,
                Manifest.permission.READ_PHONE_STATE
        };

        if (EasyPermissions.hasPermissions(this, perms)) {//检查是否获取该权限
            Logger.e("已获取定位权限");
        } else {
            EasyPermissions.requestPermissions(this, "必要的权限", 0, perms);
        }
    }

    @Override
    public void onPermissionsGranted(int requestCode, @NonNull List<String> perms) {
        Logger.e("定位请求成功");
    }

    @Override
    public void onPermissionsDenied(int requestCode, @NonNull List<String> perms) {
        Logger.e("定位请求失败");
    }
    /* #endregion ====================== 权限管理 结束 ====================== */


}